package com.airlines.base.config.websocket;

import java.io.IOException;
import java.util.concurrent.CopyOnWriteArraySet;

import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.airlines.common.TraceUtil;


/**
 * @author xxxx
 * @date 2017年12月1日 
 * @description 
 * 注意，如果是war包部署到tomcat，则@Component注解必须去掉
 */
@ServerEndpoint(value = "/websocket/{webSocketType}/{userName}")
@Component
public class BaseWebSocket {
	
	private static final Logger logger = LoggerFactory.getLogger(BaseWebSocket.class);
	
	//静态变量，用来记录当前在线连接数。应该把它设计成线程安全的。
    private static int onlineCount = 0;

    //concurrent包的线程安全Set，用来存放每个客户端对应的MyWebSocket对象。
    private static CopyOnWriteArraySet<BaseWebSocket> baseWebSocketSet = new CopyOnWriteArraySet<BaseWebSocket>();

    //与某个客户端的连接会话，需要通过它来给客户端发送数据
    private Session session;
  
    //记录当前session的身份数据
    private String webSocketType;
    private String userName;



	/**
     * 连接建立成功调用的方法*/
    @OnOpen
    public void onOpen(Session session, @PathParam("webSocketType") String webSocketType,@PathParam("userName")String userName) {        
        //判断参数是否合法
        if(StringUtils.isNotBlank(webSocketType) || StringUtils.isNotBlank(userName) ){
    		 this.webSocketType = webSocketType;
    		 this.userName = userName;
    		 this.session = session;
    		 baseWebSocketSet.add(this);     //加入set中
             addOnlineCount();           //在线数加1
             logger.info("/websocket 增加 用户，webSocketType: {} , userName : {} ",webSocketType,userName);
             logger.info("/websocket 增加 session，当前人数:{}",getOnlineCount());
        }else{
        	logger.error("/websocket 增加session验证失败，webSocketType: {} , userName : {} ",webSocketType,userName);
        }
       
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose() {
    	baseWebSocketSet.remove(this);  //从set中删除
        subOnlineCount();           //在线数减1
        logger.info("/websocket 移除用户，webSocketType: {} , userName : {} ",this.webSocketType,this.userName);
        logger.info("/websocket 移除 session，当前人数:{}",getOnlineCount());
    }

	/**
	 * 收到客户端消息后调用的方法
	 * @param message 客户端发过来的消息
	 * @param session
	 */
    @OnMessage
    public void onMessage(String message, Session session) {
        logger.info("/websocket 来自客户端的消息:{}",message);
    }

    @OnError
    public void onError(Session session, Throwable error) {
        logger.error("/websocket 发生错误:{}",TraceUtil.getTrace(error));
    }


    public void sendMessage(String message)  {
    	if(this.session.isOpen()){
    		try {
    			this.session.getBasicRemote().sendText(message);
    		} catch (IOException e) {
    			 logger.error("/websocket 发送消息错误:{}",TraceUtil.getTrace(e));
    		}
    	}
        
    }

    public static synchronized int getOnlineCount() {
        return onlineCount;
    }

    public static synchronized void addOnlineCount() {
    	BaseWebSocket.onlineCount++;
    }

    public static synchronized void subOnlineCount() {
    	BaseWebSocket.onlineCount--;
    }
    
    public static CopyOnWriteArraySet<BaseWebSocket> getQmpWebSocketSet(){
    	return baseWebSocketSet;
    }
    

    public String getWebSocketType() {
		return this.webSocketType;
	}

	public String getUserName() {
		return this.userName;
	}
}
